package be.darling.scrt.generator;

import be.darling.scrt.data.Condition;

import be.darling.scrt.data.ObservedValues;
import be.darling.scrt.data.Randomization;
import be.darling.scrt.utilities.Plugin;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Node;

/**
 * Created by IntelliJ IDEA.
 * User: geert
 * Date: Nov 20, 2007
 * Time: 8:45:28 PM
 * To change this template use File | Settings | File Templates.
 */
public abstract class Generator implements  Plugin {

    private HashMap<String, Object> options = new HashMap<String, Object>();
    private Node nodeOptions;
    private String type;
    private String name;
    private String description;

    Map<String, Condition> conditions = new HashMap<String, Condition>();

    private Long maxTotalIterations, maxRandomIterations;

    //int iterations;
    boolean complete; // exhaustive ???

    List<Condition> first;
    
    // iterations , estimate?
    // keep an estimate number of iterations!!!
    public abstract List<Condition> generate(long nr, List<Condition> previous); // params nr and previous?
    
    public Object getOption(String key)
    {
        return options.get(key);
    }

    public void setOptions(Node options) {
        this.nodeOptions = options;
    }

    public void setOptions(HashMap<String, Object> options) {
        this.options.putAll(options);
    }

    public synchronized void addCondition(Condition condition) {
        conditions.put(condition.getName().toLowerCase(),condition);
    }

    public Condition getCondition(String labelName) {
        // case sensitive ??
        return conditions.get(labelName.toLowerCase());
    }

    public Map<String, Condition> getConditions() {
        return conditions;
    }

    public void init()
    {
        if ("complete".equalsIgnoreCase((String) options.get("modus"))){
            complete = true;
        }
        if ("random".equalsIgnoreCase((String) options.get("modus"))){
            complete = false;
            try {
                maxTotalIterations = Long.parseLong( (String)options.get("maxTotalIterations") );
                maxRandomIterations = Long.parseLong( (String)options.get("maxRandomIterations") );
            } catch (NumberFormatException e) {
                System.out.println("\nOo... maxTotalIterations and or maxRandomIterations are not set in the " +
                        "config file. HopeFully the defaults are set\n");
//                e.printStackTrace();
            }
            
        }
        // maxIterations ???
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public boolean isComplete()
    {
        return complete;
    }

    public void setComplete(boolean complete)
    {
        this.complete = complete;
    }

    public Long getMaxRandomIterations() {
        return maxRandomIterations;
    }

    public void setMaxRandomIterations(Long maxRandomIterations) {
        this.maxRandomIterations = maxRandomIterations;
    }

    public Long getMaxTotalIterations() {
        return maxTotalIterations;
    }

    public void setMaxTotalIterations(Long maxTotalIterations) {
        this.maxTotalIterations = maxTotalIterations;
    }

    protected List<Condition> getFirst() {
        return first;
    }

    public void setFirst(List<Condition> first) {
        this.first = first;
    }

    public synchronized List<Condition> getBaseList(){
        /*if (first == null){
            first = new ArrayList();
            for (Iterator<Condition> labelIterator = labels.iterator(); labelIterator.hasNext();) {
                Condition label = labelIterator.next();
                for (int i=0;i< count; i++){
                    first.add(label);
                }
            }
            Collections.sort(first);
        } */
        
        return new ArrayList<Condition>(first); // return a copy !!
    }

    public boolean isValid(Randomization currentIteration)
    {
        boolean valid = true;
        // iterate filters

        return valid;
    }

    public boolean isDataValid(ObservedValues observed)
    {
        boolean valid = false;
        int totalObservationsData = observed.getLabels().size();
        int totalObservationsInputFile = 0;
        for(Condition condition : conditions.values())
        {
            try {
                totalObservationsInputFile += Integer.parseInt(condition.getProperty("n") );
            } catch (Exception e) {
            }
        }

        valid = totalObservationsData == totalObservationsInputFile;
        return valid;
    }

    // helper method to convert Condition[]  to List<Condition> ??

}
